/**
  ******************************************************************************
  * @file    WF_ConnectInfraKey.c
  * @author  exatron
  * @version V1.0.0
  * @date    segunda, 22 de dezembro de 2014
  * @brief   Função para conectar a rede.
  ******************************************************************************
  * @attention
  *
  *
  ******************************************************************************
  */

/** @addtogroup WF
  * @{
  */

/* Includes ------------------------------------------------------------------*/
#include <common.h>
#include <stdlib.h>

/* External functions --------------------------------------------------------*/

/** @defgroup WF_Functions
  * @{
  */

/**
  * @brief  Função para conectar a rede.
  * @param  char *ssid: ssid da rede a conectar
  * @param  char *key: key da rede a conectar
  * @param  char *sectype: tipo de segurança da rede a conectar
  * @retval Devolve pela serial Result_t
  */
void WF_ConnectInfraKey(char *ssid, char *key, char *sectype)
{
	#ifndef DEBUG_ON_PC
	char cmd[255];
	#endif
	int i=0;

	char mode[50];
	char ip[50];
	char netmask[50];
	char gateway[50];

	bzero(mode, sizeof(mode));
	bzero(ip, sizeof(ip));
	bzero(netmask, sizeof(netmask));
	bzero(gateway, sizeof(gateway));

	strcpy(mode, aux_FileRdLine(PATH_CONF, "network", "Erro GetNetwork\r\n"));
	strcpy(ip, aux_FileRdLine(PATH_CONF, "ip", "Erro GetNetwork\r\n"));
	strcpy(netmask, aux_FileRdLine(PATH_CONF, "netmask", "Erro GetNetwork\r\n"));
	strcpy(gateway, aux_FileRdLine(PATH_CONF, "gateway", "Erro GetNetwork\r\n"));

	/* Verifica tamanho da chave */
	if(strcmp(sectype, "wep") != 0)
	{
		if(strlen(key) < 8)
		{
			aux_USART0_puts("%s=%d\r\n", "WF_CIK", Result_BadArgument);
			aux_SetBusy(FALSE);
			return;
		}
	}

	/* Verifica criptografia */
	if(strcmp(sectype, "psk") != 0)
	{
		if(strcmp(sectype, "psk2") != 0)
		{
			if(strcmp(sectype, "wep") != 0)
			{
				if(strcmp(sectype, "none") != 0)
				{
					aux_USART0_puts("%s=%d\r\n", "WF_CIK", Result_BadArgument);
					aux_SetBusy(FALSE);
					return;
				}
			}
		}
	}

	/* Fecha todos os sockets */
	for(i=0;i<(N_SOCK_TCP+N_SOCK_UDP);i++)
		aux_CloseSocket(i);

	aux_SetConnectionState(Status_ConnectionConnecting);

	/* Network config */

	#ifndef DEBUG_ON_PC
	/* Configure modo dhcp network */
	if(atoi(mode) == DHCP_NETWORK)
	{
		system("uci delete network.modo_sta > /dev/null 2> /dev/null");
		system("uci delete network.modo_ap > /dev/null 2> /dev/null");

		system("uci set network.modo_sta=interface");
		system("uci set network.modo_sta.proto=dhcp");
	}
	/* Configure modo static network */
	else if(atoi(mode) == STATIC_NETWOTK)
	{
	    /* Verifica ip */
		if(strcntc(ip,'.') < 3)
		{
	    	aux_USART0_puts("%s=%d\r\n", "WF_CIK", Result_BadArgument);
	    	aux_SetBusy(FALSE);
	    	return;
		}
	    /* Verifica netmask */
		else if(strcntc(netmask,'.') < 3)
		{
	    	aux_USART0_puts("%s=%d\r\n", "WF_CIK", Result_BadArgument);
	    	aux_SetBusy(FALSE);
	    	return;
		}
	    /* Verifica gateway */
		else if(strcntc(gateway,'.') < 3)
		{
	    	aux_USART0_puts("%s=%d\r\n", "WF_CIK", Result_BadArgument);
	    	aux_SetBusy(FALSE);
	    	return;
		}
		/* Verifica se gateway e ip são iguais */
		else if(strcmp(ip, gateway) == 0)
		{
	    	aux_USART0_puts("%s=%d\r\n", "WF_CIK", Result_BadArgument);
	    	aux_SetBusy(FALSE);
	    	return;
		}

		system("uci delete network.modo_sta > /dev/null 2> /dev/null");
		system("uci delete network.modo_ap > /dev/null 2> /dev/null");

		system("uci set network.modo_sta=interface");
		system("uci set network.modo_sta.proto=static");
		bzero(cmd,sizeof(cmd));
		sprintf(cmd,"%s%s","uci set network.modo_sta.ipaddr=",ip);
		system(cmd);
		bzero(cmd,sizeof(cmd));
		sprintf(cmd,"%s%s","uci set network.modo_sta.netmask=",netmask);
		system(cmd);
		bzero(cmd,sizeof(cmd));
		sprintf(cmd,"%s%s","uci set network.modo_sta.gateway=",gateway);
		system(cmd);
		bzero(cmd,sizeof(cmd));
		sprintf(cmd,"%s%s","uci set network.modo_sta.dns=",gateway);
		system(cmd);
	}
	else
	{
		aux_USART0_puts("%s=%d\r\n", "WF_CIK", Result_OnNetworkParameters);
		aux_SetBusy(FALSE);
		return;
	}

	/* Wireless config */
	system("uci delete wireless.modo_ap > /dev/null 2> /dev/null");
	system("uci delete wireless.modo_sta > /dev/null 2> /dev/null");
	system("uci set wireless.modo_sta=wifi-iface");
	system("uci set wireless.modo_sta.device=radio0");
	system("uci set wireless.modo_sta.network=modo_sta");
	system("uci set wireless.modo_sta.mode=sta");
	bzero(cmd,sizeof(cmd));
	sprintf(cmd,"%s%s%s","uci set wireless.modo_sta.ssid='",ssid,"'");
	system(cmd);
	bzero(cmd,sizeof(cmd));
	sprintf(cmd,"%s%s","uci set wireless.modo_sta.encryption=",sectype);
	system(cmd);
	bzero(cmd,sizeof(cmd));
	sprintf(cmd,"%s%s","uci set wireless.modo_sta.key=",key);
	system(cmd);

	/* DHCP config */
	system("uci delete dhcp.modo_ap > /dev/null 2> /dev/null");

	/* Firewall */
	system("uci delete firewall.modo_sta_zone > /dev/null 2> /dev/null");
	system("uci delete firewall.modo_ap_zone > /dev/null 2> /dev/null");
	system("uci set firewall.modo_sta_zone=zone");
	system("uci set firewall.modo_sta_zone.name=modo_sta");
	system("uci set firewall.modo_sta_zone.network=modo_sta");
	system("uci set firewall.modo_sta_zone.input=ACCEPT");
	system("uci set firewall.modo_sta_zone.output=ACCEPT");
	system("uci set firewall.modo_sta_zone.forward=REJECT");

	system("uci delete firewall.modo_ap_rule_dhcp > /dev/null 2> /dev/null");

	system("uci commit");
	#endif

	aux_FileWrLine(PATH_CONF, "ssid", ssid, "Erro setando ssid\r\n");

	aux_SetConnectionState(Status_ConnectionConnected);

	aux_USART0_puts("%s=%d\r\n", "WF_CIK", Result_Ok);

	system("reboot -f > /dev/null 2> /dev/null");
}

/**
  * @}
  */

/**
  * @}
  */



